package com.nbsaas.boot.controller.stream;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/stream")
public class StreamController {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @GetMapping("/jsonStream")
    public StreamingResponseBody jsonStreamResponse() {
        return outputStream -> {
            try {
                String[] messages = {"Message 1", "Message 2", "Message 3"};
                for (String message : messages) {
                    // 逐步写入 JSON 格式数据
                    String json = objectMapper.writeValueAsString(new Message(message));
                    outputStream.write(json.getBytes());
                    outputStream.flush();  // 立即发送数据
                    Thread.sleep(1000);    // 模拟延时
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        };
    }

    @GetMapping("/api/stream/sse")
    public SseEmitter streamSse() {
        SseEmitter emitter = new SseEmitter();

        new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    emitter.send("Data chunk " + i);  // 向客户端发送数据
                    TimeUnit.SECONDS.sleep(1);        // 模拟长时间任务
                }
                emitter.complete(); // 完成流式响应
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e); // 错误时终止
            }
        }).start();

        return emitter;
    }

    // 用于封装每条消息
    static class Message {
        private String text;

        public Message(String text) {
            this.text = text;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }
    }
}
